From 29a164e79929f72938a2ba700884d8518d9e8c1c Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Mon, 20 Feb 2006 15:15:10 +0000 Subject: [PATCH] Eliminate tss - tss is meaningless in a paravirtualized kernel and consumes 25% of the per-cpu area. Add CONFIG_X86_NO_TSS to exclude all code which references tss. Based on a patch by Jan Beulich Signed-off-by: Christian Limpach --- linux-2.6-xen-sparse/arch/x86_64/Kconfig | 5 +++++ .../arch/x86_64/kernel/asm-offsets.c | 2 ++ .../arch/x86_64/kernel/init_task.c | 3 +++ .../arch/x86_64/kernel/process-xen.c | 19 ++++++++++++++++--- .../arch/x86_64/kernel/setup64-xen.c | 17 ++++++++++++++--- .../arch/x86_64/kernel/traps-xen.c | 2 ++ .../drivers/xen/core/smpboot.c | 1 - .../include/asm-x86_64/mach-xen/asm/desc.h | 2 ++ .../asm-x86_64/mach-xen/asm/processor.h | 9 ++++++++- 9 files changed, 52 insertions(+), 8 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/x86_64/Kconfig b/linux-2.6-xen-sparse/arch/x86_64/Kconfig index be4c1e0301..eaadb1f129 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig +++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig @@ -125,6 +125,11 @@ config X86_64_XEN help This option will compile a kernel compatible with Xen hypervisor +config X86_NO_TSS + bool + depends on X86_64_XEN + default y + # # Define implied options from the CPU selection here # diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/asm-offsets.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/asm-offsets.c index 38834bbbae..06cf05867f 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/asm-offsets.c +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/asm-offsets.c @@ -66,7 +66,9 @@ int main(void) DEFINE(pbe_address, offsetof(struct pbe, address)); DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); DEFINE(pbe_next, offsetof(struct pbe, next)); +#ifndef CONFIG_X86_NO_TSS BLANK(); DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); +#endif return 0; } diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/init_task.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/init_task.c index ce31d904d6..9c141e1a6b 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/init_task.c +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/init_task.c @@ -37,6 +37,8 @@ union thread_union init_thread_union struct task_struct init_task = INIT_TASK(init_task); EXPORT_SYMBOL(init_task); + +#ifndef CONFIG_X86_NO_TSS /* * per-CPU TSS segments. Threads are completely 'soft' on Linux, * no more per-task TSS's. The TSS size is kept cacheline-aligned @@ -45,5 +47,6 @@ EXPORT_SYMBOL(init_task); * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; +#endif #define ALIGN_TO_4K __attribute__((section(".data.init_task"))) diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c index a6fcc6a408..579c5944a5 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c @@ -289,16 +289,28 @@ void exit_thread(void) kprobe_flush_task(me); if (me->thread.io_bitmap_ptr) { +#ifndef CONFIG_X86_NO_TSS struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); +#endif +#ifdef CONFIG_XEN + static physdev_op_t iobmp_op = { + .cmd = PHYSDEVOP_SET_IOBITMAP + }; +#endif kfree(t->io_bitmap_ptr); t->io_bitmap_ptr = NULL; /* * Careful, clear this in the TSS too: */ +#ifndef CONFIG_X86_NO_TSS memset(tss->io_bitmap, 0xff, t->io_bitmap_max); - t->io_bitmap_max = 0; put_cpu(); +#endif +#ifdef CONFIG_XEN + HYPERVISOR_physdev_op(&iobmp_op); +#endif + t->io_bitmap_max = 0; } } @@ -463,7 +475,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread; int cpu = smp_processor_id(); +#ifndef CONFIG_X86_NO_TSS struct tss_struct *tss = &per_cpu(init_tss, cpu); +#endif physdev_op_t iopl_op, iobmp_op; multicall_entry_t _mcl[8], *mcl = _mcl; @@ -482,10 +496,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) /* * Reload esp0, LDT and the page table pointer: */ - tss->rsp0 = next->rsp0; mcl->op = __HYPERVISOR_stack_switch; mcl->args[0] = __KERNEL_DS; - mcl->args[1] = tss->rsp0; + mcl->args[1] = next->rsp0; mcl++; /* diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup64-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup64-xen.c index a1bcc022b4..6bed7e2196 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup64-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup64-xen.c @@ -203,8 +203,10 @@ void pda_init(int cpu) pda->irqstackptr += IRQSTACKSIZE-64; } +#ifndef CONFIG_X86_NO_TSS char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ] __attribute__((section(".bss.page_aligned"))); +#endif /* May not be marked __init: used by software suspend */ void syscall_init(void) @@ -246,18 +248,23 @@ void __cpuinit check_efer(void) void __cpuinit cpu_init (void) { int cpu = stack_smp_processor_id(); +#ifndef CONFIG_X86_NO_TSS struct tss_struct *t = &per_cpu(init_tss, cpu); unsigned long v; char *estacks = NULL; + unsigned i; +#endif struct task_struct *me; - int i; /* CPU 0 is initialised in head64.c */ if (cpu != 0) { pda_init(cpu); zap_low_mappings(cpu); - } else + } +#ifndef CONFIG_X86_NO_TSS + else estacks = boot_exception_stacks; +#endif me = current; @@ -294,6 +301,7 @@ void __cpuinit cpu_init (void) check_efer(); +#ifndef CONFIG_X86_NO_TSS /* * set up and load the per-CPU TSS */ @@ -330,6 +338,7 @@ void __cpuinit cpu_init (void) */ for (i = 0; i <= IO_BITMAP_LONGS; i++) t->io_bitmap[i] = ~0UL; +#endif atomic_inc(&init_mm.mm_count); me->active_mm = &init_mm; @@ -337,8 +346,10 @@ void __cpuinit cpu_init (void) BUG(); enter_lazy_tlb(&init_mm, me); -#ifndef CONFIG_XEN +#ifndef CONFIG_X86_NO_TSS set_tss_desc(cpu, t); +#endif +#ifndef CONFIG_XEN load_TR_desc(); #endif load_LDT(&init_mm.context); diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c index c2e1f7af6a..242fe03f5f 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c @@ -134,6 +134,7 @@ int printk_address(unsigned long address) static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, unsigned *usedp, const char **idp) { +#ifndef CONFIG_X86_NO_TSS static char ids[][8] = { [DEBUG_STACK - 1] = "#DB", [NMI_STACK - 1] = "NMI", @@ -185,6 +186,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, } #endif } +#endif return NULL; } diff --git a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c index 4c72930e86..05f67a70e0 100644 --- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c +++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c @@ -237,7 +237,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) #ifdef __x86_64__ cpu_pda(cpu)->pcurrent = idle; cpu_pda(cpu)->cpunumber = cpu; - per_cpu(init_tss,cpu).rsp0 = idle->thread.rsp; clear_ti_thread_flag(idle->thread_info, TIF_FORK); #endif diff --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/desc.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/desc.h index 26110ed80d..292f8a712e 100644 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/desc.h +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/desc.h @@ -152,6 +152,7 @@ static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned memcpy(ptr, &d, 16); } +#ifndef CONFIG_X86_NO_TSS static inline void set_tss_desc(unsigned cpu, void *addr) { /* @@ -165,6 +166,7 @@ static inline void set_tss_desc(unsigned cpu, void *addr) (unsigned long)addr, DESC_TSS, IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); } +#endif static inline void set_ldt_desc(unsigned cpu, void *addr, int size) { diff --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h index 681176025b..6fe7ccd450 100644 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h @@ -196,7 +196,9 @@ static inline void clear_in_cr4 (unsigned long mask) #define IO_BITMAP_BITS 65536 #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) +#ifndef CONFIG_X86_NO_TSS #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) +#endif #define INVALID_IO_BITMAP_OFFSET 0x8000 struct i387_fxsave_struct { @@ -217,6 +219,7 @@ union i387_union { struct i387_fxsave_struct fxsave; }; +#ifndef CONFIG_X86_NO_TSS struct tss_struct { u32 reserved1; u64 rsp0; @@ -240,8 +243,10 @@ struct tss_struct { unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; } __attribute__((packed)) ____cacheline_aligned; -extern struct cpuinfo_x86 boot_cpu_data; DECLARE_PER_CPU(struct tss_struct,init_tss); +#endif + +extern struct cpuinfo_x86 boot_cpu_data; #ifdef CONFIG_X86_VSMP #define ARCH_MIN_TASKALIGN (1 << INTERNODE_CACHE_SHIFT) @@ -283,9 +288,11 @@ struct thread_struct { .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } +#ifndef CONFIG_X86_NO_TSS #define INIT_TSS { \ .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } +#endif #define INIT_MMAP \ { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL } -- 2.30.2